home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
pas_all.zip
/
TI174.ASC
< prev
next >
Wrap
Text File
|
1992-09-02
|
12KB
|
463 lines
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 1/7
TITLE : Files Open Extend
The following is public domain information that has been uploaded
to our Forum on CompuServe. As a courtesy to our users that do
not have immediate access to CompuServe, Technical Support
distributes these routines free of charge.
However, because these routines are public domain programs, not
developed by Borland International, we are unable to provide any
technical support or assistance using these routines. If you need
assistance using these routines, or are experiencing difficu
Written by:
Randy Forgaard, CompuServe 70307,521
Many thanks to Bela Lubkin (CompuServe 76703,3015) for
masterminding this idea, and Kim Kokkonen (CompuServe 72457,2131)
for helping me debug it. For more discussion of Handle Tables and
the implementation of DOS redirection, please see Stan Mitchell,
"Co
Due to a limitation of DOS, Turbo Pascal version 3.0 only allows
up to 15 files at a time to be open. The following method allows
you to have up to 96 files open simultaneously under DOS 2.0 or
2.1, or 252 files open simultaneously under DOS 3.0 or grea
TO USE THIS TECHNIQUE:
You need the routines and global declarations below. Everywhere
in your program that you Reset or Rewrite a file "f" for the
first time, insert an "OpenExtend(f);" invocation immediately
after the Reset or Rewrite. Each time your program calls one of
Turb
At the top of your program, prior to the "program" statement, put
the compiler directive {$F252}. (You may use a value smaller than
252 if you wish. Under DOS 2.0/2.1, values above 96 have
no additional benefit. Each larger value for the {$F} directive
uses 2 additional bytes in the program's global data space.) The
value you specify for the {$F} directive is the maximum number of
files you will be able to have open at the same time in your
Edit your CONFIG.SYS file (see the DOS manual for details) so
that it includes a line that says "FILES=XXX". XXX should be a
number that is 3 greater than the value you specified for the
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 2/7
TITLE : Files Open Extend
{$F} directive (larger values will provide no additional benefit
wit
THE TECHNICAL DETAILS:
Much of the following information is not documented in the DOS
Technical Reference manual.
Under DOS 1.0 and 1.1, all files were accessed via File Control
Blocks (FCB's). There was no limit to the number of FCB's that a
program could use, so there was no limit to the number of files
open simultaneously.
Under DOS 2.0 and greater, an alternate (and preferable) method
of accessing files was introduced which uses a 2-byte integer
called a "handle" to refer to a file. A "handle" file is
described using a data structure called a Device Control Block
(DCB). Ho
So that I/O redirection can be supported, the DCB numbers are not
used directly when accessing files. Instead, a file "handle" is
used. A "handle" is an index into a 20-byte array, called the
Handle Table, which is located at offset 18H of the Program Seg
Every time a new handle file is opened, a new handle gets used.
Since there are only 20 slots available in the Handle Table for a
program, DOS only allows a "process" to have a maximum of 20 file
handles in use simultaneously (and the first 5 entries are
The size of the DCB Table (i.e., the maximum number of
files/devices that can be open simultaneously in the whole
computer) is controlled by the FILES=XXX entry in the CONFIG.SYS
file. The minimum number of slots is 8. Under DOS 2.0/2.1, the
maximum numbe
A single program can use all of the DCB's in the DCB Table
(except for the 3 reserved by DOS) all on its own, by effectively
bypassing the Handle Table in the PSP, except on a temporary
basis. The program can accomplish this feat by using, say, only
one e
The OpenExtend, UnExtend, and ReExtend routines below use this
technique. OpenExtend(f) is used on a previously-opened file,
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 3/7
TITLE : Files Open Extend
"f." It removes f's DCB number from the Handle Table, and stores
that DCB number in place of the file handle in Turbo's data struc
To obtain the address of the Handle Table, which is at offset 18H
in the PSP, the program needs to find the address of its PSP.
Normally, this is very easy: when DOS loads a .COM file, the
address of the PSP is just CS:0000. Using CS:0000 in this manner
w
To allow the program to work correctly both when running in
memory and when run as a .COM file, we use the DOS function call
62H, "Get Program Segment Prefix Address (PSP)." This function
call is available in DOS 3.0 and higher. There is an identical
func
To decide whether to use function 51H or 62H, we call DOS
function 30H, "Get DOS Version Number," to determine which
version of DOS is running. This strategy for obtaining the Handle
Table address is implemented in the GetHandleTableAddr function,
below,
Note: This technique will not interfere with overlays in your
program (since it only uses the Handle Table slot temporarily),
provided that your program leaves at least one DCB available for
use by the Turbo run-time library to read in overlay files.
{$F252}
const
LastHandle = 19; {Highest-numbered handle}
UnusedHandle = $FF; {DcbTable entry that denotes an unused
handle}
type
HandleTable = array[0..LastHandle] of Byte;
HandleTablePtr = ^HandleTable;
const
TablePtrOk: Boolean = false; {"True" iff TablePtr is
initialized}
var
TablePtr: HandleTablePtr; {Points to Handle Table for this
process}
SaveDcb: Byte; {Temporary variable for a DCB number during a
function
call}
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 4/7
TITLE : Files Open Extend
{Internal routine. Returns the address of the Handle Table,
which is at offset 18H in the PSP.}
function GetHandleTableAddr: HandleTablePtr;
var
regs: record
case Integer of
1: (AX, BX, CX, DX, BP, SI, DI, DS, ES, Flags:
Integer);
2: (AL, AH, BL, BH, CL, CH, DL, DH: Byte)
end;
begin
regs.AH := $30;
MsDos(regs); {Get DOS version number}
case regs.AL of
0: begin
writeln('This program only works with DOS 2.0 and
higher');
Halt
end;
2: regs.AH := $51; {Undocumented, but works with DOS 2.0/2.1
(and 3.X)}
else regs.AH := $62 {Works with DOS 3.0 and higher}
end;
MsDos(regs); {Get PSP address}
GetHandleTableAddr := Ptr(regs.BX, $18)
end {GetHandleTableAddr};
{Causes "f" to become an "extended" file; i.e., to remain open
without using up any file handles. The parameter "f" must be any
Turbo file; e.g., a File, a File of Byte, a File of Foo, Text,
etc. This routine should be called immediately after the Reset
procedure OpenExtend (var f);
var
handle: Integer absolute f;
begin
if not TablePtrOk then
begin
TablePtr := GetHandleTableAddr;
TablePtrOk := true
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 5/7
TITLE : Files Open Extend
end;
SaveDcb := TablePtr^[handle];
TablePtr^[handle] := UnusedHandle;
handle := SaveDcb
end {OpenExtend};
{Unextends the extended file "f," so that it can be used by any
of Turbo's built-in file routines. Note that "f" must have been
converted to an extended file by OpenExtend before invoking
UnExtend(f). After calling UnExtend, and then invoking the Turbo
f
procedure UnExtend (var f);
var
handle: Integer absolute f;
begin
SaveDcb := TablePtr^[LastHandle];
TablePtr^[LastHandle] := Lo(handle);
handle := LastHandle
end {UnExtend};
{Re-extends "f" into an extended file. Note that "f" must have
been converted to an extended file by OpenExtend, and then
unextended using UnExtend, before "f" can re-extended using
ReExtend. ReExtend(f) should be invoked immediately after any
normal Tu
procedure ReExtend (var f);
var
handle: Integer absolute f;
begin
handle := TablePtr^[LastHandle];
TablePtr^[LastHandle] := SaveDcb
end {ReExtend};
{Example program -- This program opens as many Text files as it
can, until DOS runs out of room in its DCB Table. It then
reports how many files were successfully opened, writes a line to
each of them, then closes and erases each of them. Note: The
value
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 6/7
TITLE : Files Open Extend
This program takes a while to run, due to the heavy disk I/O, so
running it on a hard disk (or, even better, a RAM disk) is
recommended. Make sure that you are running the program in a
subdirectory, so that you don't run up against the DOS limit on
the n
const
MaxCount = 255;
var
num: string[6];
f: array[1..MaxCount] of Text;
i, count: Integer;
result: Byte;
begin
writeln('Opening files...');
i := 0;
repeat
i := i + 1;
Str(i, num);
Assign(f[i], 'junk' + num + '.txt');
{$I-} Rewrite(f[i]); {$I+}
result := IOResult;
if result = 0 then OpenExtend(f[i])
until result <> 0;
count := i - 1;
writeln('Successfully opened ', count, ' files at the same
time. ',
'Writing to each file...');
for i := 1 to count do
begin
UnExtend(f[i]);
writeln(f[i], 'This is a test');
ReExtend(f[i])
end;
PRODUCT : Turbo Pascal NUMBER : 174
VERSION : 3.01A
OS : PC DOS
DATE : August 1, 1986 PAGE : 7/7
TITLE : Files Open Extend
writeln('Closing and erasing each file...');
for i := 1 to count do
begin
UnExtend(f[i]);
Close(f[i]);
Erase(f[i]);
ReExtend(f[i])
end;
writeln('Done.')
end.
(**)
DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.